import logging
import random
import re
import uuid

from flask import render_template, g, request, abort, make_response, jsonify, current_app, session
from flask_mail import Message
from info import constants
from sqlalchemy import and_

from info import redis_store, db, mail
from info.models import User, Receiving, Goods, Shop_cart
from info.modules.profile import profile_blu
from info.utils.common import user_login_data
from info.utils.image_storage import storage
from info.utils.response_code import RET


# type="button" class="save_info"

@profile_blu.route('/base_user', methods=['POST', "GET"])
@user_login_data
def base_user():
    """更改用户资料"""

    user = g.user
    if request.method == "GET":

        if not user:
            return render_template('common/404.html')
        data = {
            "user_info": user.to_dict(),
        }
        return render_template("index/xiugaiziliao.html", data=data)

    json_data = request.json
    real_name = json_data.get('real_name')  # 真实姓名
    nick_name = json_data.get('nick_name')
    gender = json_data.get('gender')  # 性别
    mobile = json_data.get('mobile')  # 电话号码
    e_mail = json_data.get('e_mail')  # 邮箱
    birthday = json_data.get('birthday')  # 出生日期
    area_addr = json_data.get('area_addr')  # 居住地址

    # 校检参数 判断参数是否存在
    if not all([nick_name, real_name, gender, mobile, e_mail, birthday, area_addr]):
        return jsonify(errno=RET.PARAMERR, errmsg='请填写完整信息')
    # 判断性别的参数是否正确
    if gender not in (['MAN', 'WOMAN', 'SECRECY']):
        return jsonify(errno=RET.PARAMERR, errmsg='请填写完整信息')
    # 判断电话号码格式是否正确
    if not re.match(r'1[3456789]\d{9}$', mobile):
        ret = {'errno': RET.PARAMERR, 'errmsg': '手机号不存在'}
        return jsonify(ret)
    # 更新并保存数据
    user.nick_name = nick_name
    user.real_name = real_name
    user.gender = gender
    user.mobile = mobile
    user.e_mail = e_mail
    user.birthday = birthday
    user.area_addr = area_addr

    # 提交数据
    try:
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        # 事务回滚
        db.session.rollback()
        return jsonify(errno=RET.DBERR, errmsg='保存数据失败')

    # 返回响应
    return jsonify(errno=RET.OK, errmsg='保存成功')


@profile_blu.route('/goods_addr', methods=['GET', 'POST'])
@user_login_data
def goods_addr():
    """收货地址"""

    user = g.user
    if request.method == 'GET':
        if not user:
            return render_template('common/404.html')
        data = {
            'base_user_info': user.to_dict()
        }

        return render_template('./index/dizhiguanli.html', data=data)


@profile_blu.route('/save_addr', methods=['POST'])
@user_login_data
def save_addr():
    """修改收货地址"""
    user = g.user

    json_data = request.json
    addr_name = json_data.get('addr_name')
    addr_area = json_data.get('addr_area')
    addr_detail = json_data.get('addr_detail')
    mobile = json_data.get('addr_mobile')
    r_id = json_data.get('addr_id')

    # 判断参数
    if not all([addr_area, addr_name, addr_detail, mobile, r_id]):
        return jsonify(errno=RET.PARAMERR, errmsg='请填写完整信息')
        # 校验手机号是否正确
    if not re.match('1[35678]\\d{9}', mobile):
        return jsonify(errno=RET.PARAMERR, errmsg="手机号格式不正确")

    # 查询数据库中是否存在该收货信息,如果存在,就修改
    try:
        receiving = Receiving.query.filter(Receiving.r_id == r_id).one()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='修改错误')

    # 修改信息
    receiving.r_addr = addr_detail
    receiving.user_id = user.u_id
    receiving.r_addr_area = addr_area
    receiving.r_name = addr_name
    receiving.r_mobile = mobile

    try:
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.rollback()
        return jsonify(errno=RET.OK, errmsg='修改失败!')

    return jsonify(errno=RET.OK, errmsg='修改成功!', r_name=receiving.r_name, r_addr=receiving.r_addr,
                   r_mobile=receiving.r_mobile, r_addr_area=receiving.r_addr_area)


@profile_blu.route('/remove_addr', methods=['POST'])
@user_login_data
def remove_addr():
    """删除收货地址"""

    addr_id = request.json.get('addr_id')

    try:
        receiving = Receiving.query.filter(Receiving.r_id == addr_id).one()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='未找到该地址')

    # 删除对象
    try:
        db.session.delete(receiving)
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errno=RET.DBERR, errmsg='删除失败')

    return jsonify(errno=RET.OK, errmsg='删除成功')


@profile_blu.route('/append_addr', methods=['POST'])
@user_login_data
def append_addr():
    """添加收货地址"""
    user = g.user

    json_data = request.json
    addr_name = json_data.get('addr_name')
    addr_area = json_data.get('addr_area')
    addr_detail = json_data.get('addr_detail')
    mobile = json_data.get('addr_mobile')

    # 判断参数
    if not all([addr_area, addr_name, addr_detail, mobile]):
        return jsonify(errno=RET.PARAMERR, errmsg='请填写完整信息')
        # 校验手机号是否正确
    if not re.match('1[35678]\\d{9}', mobile):
        return jsonify(errno=RET.PARAMERR, errmsg="手机号格式不正确")

    receiving = Receiving()
    receiving.r_addr = addr_detail
    receiving.user_id = user.u_id
    receiving.r_addr_area = addr_area
    receiving.r_name = addr_name
    receiving.r_mobile = mobile

    try:
        db.session.add(receiving)
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.rollback()
        return jsonify(errno=RET.OK, errmsg='添加失败!')

    return jsonify(errno=RET.OK, errmsg='添加成功!', r_name=receiving.r_name, r_addr=receiving.r_addr,
                   r_mobile=receiving.r_mobile, r_addr_area=receiving.r_addr_area)


@profile_blu.route('/binding', methods=["POST", 'GET'])
@user_login_data
def binding():
    '''绑定手机号'''
    user = g.user
    data = {
        'user_info': user.to_dict()
    }
    if request.method == 'GET':
        if not user:
            return render_template('common/404.html')
        return render_template('./index/bangdingshouji.html', data=data)
    else:
        # 1. 获取参数
        param_dict = request.json
        mobile = param_dict.get("mobile")
        smscode = param_dict.get("smscode")
        print(mobile)
        print(smscode)
        # 2. 校验参数
        if not all([mobile, smscode]):
            return jsonify(errno=RET.PARAMERR, errmsg="参数")

        # 校验手机号是否正确
        if not re.match('1[35678]\\d{9}', mobile):
            return jsonify(errno=RET.PARAMERR, errmsg="手机号格式不正确")

        # 3. 从redis的真实的短信验证码内容
        try:
            real_sms_code = redis_store.get("SMS_" + mobile)
        except Exception as e:
            current_app.logger.error(e)
            return jsonify(errno=RET.DBERR, errmsg="数据查询失败")

        # 4. 校验用户输入的短信验证码内容和真实验证码内容是否一致
        if real_sms_code != smscode:
            return jsonify(errno=RET.DATAERR, errmsg="验证码输入错误")

        # 2. 获取当前登录用户的信息

        # 更新数据
        user.bind_mobile = mobile
        user.mobile_status = 1
        try:
            db.session.commit()
        except Exception as e:
            current_app.logger.error(e)
            return jsonify(errno=RET.DBERR, errmsg="数据提交失败")
        return jsonify(errno=RET.OK, errmsg='绑定成功')


@profile_blu.route('/smscode', methods=['POST', 'GET'])
def send_sms():
    '''发送手机验证码'''
    params_dict = request.json
    mobile = params_dict.get('mobile')
    # 2校验  参数是否符合规则 判断是否为空
    if not mobile:
        ret = {'errno': RET.PARAMERR, 'errmsg': '参数有误'}
        return jsonify(ret)
    # 手机号的正则校验
    if not re.match(r'1[3456789]\d{9}', mobile):
        ret = {'errno': RET.PARAMERR, 'errmsg': '手机号格式不正确'}
        return jsonify(ret)

    sms_code_str = "%06d" % random.randint(0, 999999)
    current_app.logger.error('短信验证码是:::%s' % sms_code_str)

    print(sms_code_str)
    # 验证码内容存到redis
    try:
        redis_store.set('SMS_' + mobile, sms_code_str, 60)
    except Exception as e:
        current_app.logger.error(e)
        ret = {'errno': RET.DBERR, 'errmsg': '数据保存失败'}
        return jsonify(ret)
    # 7返回相应 发送是否成功
    ret = {'errno': RET.OK, 'errmsg': '发送成功'}
    return jsonify(ret)


@profile_blu.route('/e_mail', methods=['POST', 'GET'])
@user_login_data
def e_mail():
    '''发送邮件'''
    user = g.user
    if request.method == 'POST':
        email_addr = request.json.get('email_addr')
        try:
            user_ret = User.query.filter(User.bind_e_mail == email_addr).first()
        except Exception as e:
            current_app.logger.error(e)
            return jsonify(errno=RET.DBERR, errmsg="数据查询失败")
        print('----------------')
        ret = re.match(r'^[0-9a-zA-Z_]{0,19}@[0-9a-zA-Z]{1,13}\.[com,cn,net]{1,3}$', email_addr)
        print(ret)
        if ret == None:
            return jsonify(errno=RET.DBERR, errmsg="邮箱格式错误!")

        if user_ret:
            # 2. 如果邮箱或者用户名已经存在，则不允许使用
            # 3. 返回对应的数据
            return jsonify(errno=RET.PARAMERR, errmsg='邮箱已绑定其他用户!')
        else:
            # 获取uuid
            activekey = str(uuid.uuid1())
            # 去掉里面的-
            activekey = activekey.replace('-', '')

            active_addr = request.host_url + "user/active?user_id={}&activekey={}".format(user.user_id, activekey)

            # 发送激活码功能
            # sender到时候换成公司要求的邮箱 recipients是接受人的邮箱
            msg = Message('你好', sender='15658637193@163.com', recipients=[email_addr])
            # 这里的sender是发信人，写上你发信人的名字，比如张三。
            # recipients是收信人，用一个列表去表示。
            msg.body = '激活邮件'
            msg.html = '<p>欢迎激活小米商城邮箱功能!<a href = "{}">点我验证</a>,完成邮箱激活,如果有问题请联系halon,电话18512345678</p>'.format(
                active_addr)
            # 发送
            mail.send(msg)
            user = g.user
            user.activekey = activekey
            try:
                db.session.commit()
            except Exception as e:
                current_app.logger.error(e)
                db.session.rollback()
                return jsonify(errno=RET.DBERR, errmsg='绑定失败')
            return jsonify(errno=RET.OK, errmsg='发送成功')
    else:
        user = g.user
        data = {
            'user_info': user.to_dict()
        }
        return render_template('./index/bangdingyouxiang.html', data=data)


@profile_blu.route('/active')
@user_login_data
def active():
    """激活邮箱 """
    # 获取用户id
    user_id = request.args.get('user_id')
    # 获取激活码
    activekey = request.args.get('activekey')

    try:
        # 去数据库查询
        user = User.query.filter(and_(User.user_id == user_id, activekey == activekey)).first()
    except Exception as e:
        print(e)
        current_app.logger.error(e)
        return jsonify(errno=RET.THIRDERR, errmsg='发送失败')

    # 修改状态为1
    user.status = 1
    # 提交
    try:
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='提交失败')

    return render_template('./index/chenggongbangding.html')


@profile_blu.route('/send_ok')
def send_ok():
    '''绑定手机成功'''
    if request.method == 'GET':
        return render_template('./index/send_ok.html')


@profile_blu.route('/collection')
@user_login_data
def collection():
    """收藏页面显示"""
    # 1获取参数
    # 当前页数
    p = request.args.get('p', 1)
    try:
        p = int(p)
    except Exception as e:
        current_app.logger.error(e)
        p = 1

    # 获取数据
    user = g.user
    if not user:
        return render_template('common/404.html')
    collections = []  # 存放新闻对象的列表
    current_page = 1  # 当前页
    total_page = 1  # 总页数

    try:
        pagination = user.collection_goods.paginate(p, constants.USER_COLLECTION_MAX_NEWS, False)
        collections = pagination.items
        current_page = pagination.page
        total_page = pagination.pages
    except Exception as e:
        current_app.logger.error(e)

    collection_dict_li = []
    # 转为字段数据存到列表里
    for goods in collections:
        collection_dict_li.append(goods.to_dict())

    print('total_page', total_page)
    print('current_page', current_page)
    # 所有数据
    data = {"total_page": total_page, "current_page": current_page, "collections": collection_dict_li,
            'user_info': user.to_dict(), }

    return render_template('index/wodeshoucang.html', data=data)


@profile_blu.route('collect_remove', methods=['POST', 'GET'])
@user_login_data
def remove_collect():
    """删除收藏"""

    user = g.user
    json_data = request.json
    goods_id = json_data.get('goods_id')

    print('商品id----------------', goods_id)
    if not goods_id:
        return jsonify(errno=RET.PARAMERR, errmsg='参数错误')

    try:
        goods_id = int(goods_id)
    except Exception as e:
        current_app.logger.error(e)

    # 查询出该被收藏的商品
    try:
        goods = Goods.query.filter(Goods.g_id == goods_id).one()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='没有收藏该商品')

    # 从数据库中删除关系
    try:
        user.collection_goods.remove(goods)
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errno=RET.DBERR, errmsg='删除失败!')

    return jsonify(errno=RET.OK, errmsg='删除成功!')


@profile_blu.route('my_shopcar', methods=['POST', 'GET'])
@user_login_data
def my_shop_car():
    """我的购物车"""

    user = g.user

    if not user:
        return render_template('./index/login.html')

    shop_car = None
    # 根据用户id查询出购物车内容
    print(user.u_id)

    try:
        shop_car = Shop_cart.query.filter(Shop_cart.c_user_id == user.u_id).first()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="购物车为空")

    data = {
        'user_info': user.to_dict(),
        'shop_car': shop_car
    }

    return render_template('./index/wodegouwuche.html', data=data)


@profile_blu.route('shop_car_remove', methods=['POST', 'GET'])
@user_login_data
def remove_shop_car():
    """删除购物车商品"""

    user = g.user
    json_data = request.json
    goods_id = json_data.get('goods_id')

    if not goods_id:
        return jsonify(errno=RET.PARAMERR, errmsg='参数错误')

    try:
        goods_id = int(goods_id)
    except Exception as e:
        current_app.logger.error(e)

    # 查询出该被加入购物车的商品
    shop_car = None
    try:
        goods = Goods.query.filter(Goods.g_id == goods_id).one()
        shop_car = Shop_cart.query.filter(Shop_cart.c_user_id == user.u_id).first()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='没有该商品')

    # 从数据库中删除关系
    try:
        shop_car.shop_goods.remove(goods)
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errno=RET.DBERR, errmsg='删除失败!')

    return jsonify(errno=RET.OK, errmsg='删除成功!')


@profile_blu.route('/zfmm', methods=['POST', "GET"])
@user_login_data
def zhifumima():
    """设置支付密碼"""
    user = g.user
    if request.method == 'GET':
        if not user:
            return render_template('common/404.html')
        data = {
            'user_info': user.to_dict()
        }
        return render_template('index/zhifumima.html', data=data)
    elif request.method == 'POST':
        # 1. 获取参数
        param_dict = request.json
        # 支付密码
        zfpwd01 = param_dict.get("zfpwd01")
        # 确认密码
        zfpwd02 = param_dict.get("zfpwd02")

        # 2. 校验参数
        if not all([zfpwd01, zfpwd02]):
            return jsonify(errno=RET.PARAMERR, errmsg="参数")
        # 判断密码是否相同
        if zfpwd01 != zfpwd02:
            return jsonify(errno=RET.PWDERR, errmsg="密码不一致")
        # 5. 如果一致，初始化 User 模型，并且赋值属性添加数据库
        user = g.user
        user.zfmm_password = zfpwd01  # 最后登录时间

        # 5.1 添加到数据库
        try:
            db.session.add(user)
            db.session.commit()
        except Exception as e:
            current_app.logger.error(e)
            db.session.rollback()
            return jsonify(errno=RET.DBERR, errmsg="设置失败")

        # 7. 返回响应
        return jsonify(errno=RET.OK, errmsg="修改支付密码成功!")


@profile_blu.route('/pic_info', methods=["GET", "POST"])
@user_login_data
def pic_info():
    """上传头像"""
    user = g.user
    if request.method == "GET":
        if not user:
            return render_template('common/404.html')
        return render_template('index/pic_info.html', data={"user_info": user.to_dict()})

    # 1.获取上传的文件
    try:
        file = request.files.get('avatar')  # 获取文件对象
        avatar_file = file.read()  # 读取数据
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.PARAMERR, errmsg="读取文件出错")

    print("文件对象：", file)
    print("文件读取后数据：", avatar_file)
    # 2.保存到七牛云
    try:
        url = storage(avatar_file)
        print("url===========", url)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.THIRDERR, errmsg="上传图片出错")
    # 3把文件名字保存到数据库
    user.avatar_url = url
    try:
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="数据保存错误")

    # 4.返回响应
    return jsonify(errno=RET.OK, errmsg="OK", data={"avatar_url": constants.QINIU_DOMIN_PREFIX + url})
